package src.serverSide;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import src.dataStructures.DataType;



public class DataNames {
	private TreeMap<String, Integer> names = new TreeMap<String, Integer>();
	private Map<DataType,TreeMap<String, Integer>> namesmap = new HashMap<DataType,TreeMap<String, Integer>>();
	
	public DataNames() {
		namesmap.put(DataType.USER, new TreeMap<String, Integer>());
		namesmap.put(DataType.ITEM, new TreeMap<String, Integer>());
	}
	
	/**
	 * This method returns the ID associated with the given name
	 * @param name The name to search for
	 * @return The ID found, or -1 if not found
	 */
	public int getID(String name) {
		if (exists(name)) return names.get(name);
		else return -1;
	}
	
	/**
	 * Pairs the given name with the given ID in the list specified by type
	 * @param name The name to store as the key
	 * @param id The ID associated with the name
	 * @param type The type for the specific list to store the mapping
	 */
	public void addName(String name, int id, DataType type) {
		names.put(name, id);
		namesmap.get(type).put(name, id);
	}
	
	/**
	 * Checks whether the given name is in the system
	 * @param name The name to look for
	 * @return True if the name is found
	 */
	public boolean exists(String name) {
		return names.containsKey(name);
	}
	
	/**
	 * Checks whether the given name is in the system as that specific type
	 * @param name The name to look for
	 * @param type The type to look under
	 * @return True if the name is found
	 */
	public boolean exists(String name, DataType type) {
		return namesmap.get(type).containsKey(name);
	}
	
	/**
	 * Removes the given name from the database
	 * @param name The name to remove
	 */
	public void removeName(String name) {
		names.remove(name);
		namesmap.get(DataType.USER).remove(name);
		namesmap.get(DataType.ITEM).remove(name);
	}
	
	/**
	 * Checks to see if the given name is in the correct format
	 * @param name The name to check
	 * @return True if the name is formatted correctly
	 */
	public boolean checkNameFormat(String name) {
		System.out.println("checkNameFormat in DataNames not implemented yet");
		return true;
	}
	
	/**
	 * Retrieves a list of IDs from an alphabetical list specified
	 * @param start The start item of the list
	 * @param length The length of the list of IDs to return
	 * @param type Specifies the list to pull from
	 * @return The list of IDs
	 */
	public List<Integer> getNameList(String start, int length, DataType type) {
		TreeMap<String, Integer> names = namesmap.get(type);
		Iterator<String> i = names.keySet().iterator();
		List<Integer> list = new ArrayList<Integer>();
		while (i.hasNext() && i.next().compareTo(start) < 0);
		for (int j = 0; j < length && i.hasNext(); j++) list.add(names.get(i.next()));
		return list;
	}
	
	/**
	 * This method returns a list of ID's corresponding to substrings starting with the given string
	 * @param start The substring to search for
	 * @param maxlength The maximum number of elements to return
	 * @param type The type, user, item, or unspecified, to search for
	 * @return The list of item ID's
	 */
	public List<Integer> getSubNameList(String start, int maxlength, DataType type) {
		TreeMap<String, Integer> names = namesmap.get(type);
		Iterator<String> i = names.keySet().iterator();
		List<Integer> list = new ArrayList<Integer>();
		while (i.hasNext() && i.next().compareTo(start) < 0);
		String name;
		for (int j = 0; j < maxlength && i.hasNext() && (name = i.next()).startsWith(start); j++) 
			list.add(names.get(name));
		return list;
	}
	
}
